from config.database import AsyncSessionLocal
from config.env import RedisConfig
from module_admin.service.config_service import ConfigService
from module_admin.service.dict_service import DictDataService
from utils.log_util import logger
from aioredis import Redis, ConnectionPool, AuthenticationError, RedisError


class RedisManager:
    """
    Redis相关方法
    """

    # 全局变量来存储 Redis 连接池
    __redis_pool: Redis = None
    __connection_pool = None

    @classmethod
    async def init_redis_pool(cls) -> Redis:
        """
        应用启动时初始化redis连接

        :return: Redis连接对象
        """
        logger.info('开始连接redis...')
        if cls.__redis_pool is None:
            cls.__connection_pool = ConnectionPool.from_url(
                url=f'redis://{RedisConfig.redis_host}',
                port=RedisConfig.redis_port,
                db=RedisConfig.redis_database,
                username=RedisConfig.redis_username,
                password=RedisConfig.redis_password,
                max_connections=10,  # 连接池的最大连接数
                # timeout=5,  # 连接超时时间（秒）
                encoding="utf-8",
                decode_responses=True,
            )
        if cls.__redis_pool is None:
            cls.__redis_pool = await Redis(connection_pool=cls.__connection_pool)
        try:
            connection = await cls.__redis_pool.ping()
            if connection:
                logger.info('redis连接成功')
            else:
                logger.error('redis连接失败')
        except AuthenticationError as e:
            logger.error(f'redis用户名或密码错误，详细错误信息：{e}')
        except TimeoutError as e:
            logger.error(f'redis连接超时，详细错误信息：{e}')
        except RedisError as e:
            logger.error(f'redis连接错误，详细错误信息：{e}')
        return cls.__redis_pool

    @classmethod
    async def close_redis_pool(cls):
        """
        应用关闭时关闭redis连接

        :param app: fastapi对象
        :return:
        """
        await cls.__redis_pool.close()
        logger.info('关闭redis连接成功')

    @classmethod
    async def init_sys_dict(cls, redis):
        """
        应用启动时缓存字典表

        :param redis: redis对象
        :return:
        """
        async with AsyncSessionLocal() as session:
            await DictDataService.init_cache_sys_dict_services(session, redis)

    @classmethod
    async def init_sys_config(cls, redis):
        """
        应用启动时缓存参数配置表

        :param redis: redis对象
        :return:
        """
        async with AsyncSessionLocal() as session:
            await ConfigService.init_cache_sys_config_services(session, redis)

    @classmethod
    def get_redis(cls) -> Redis:
        if cls.__redis_pool is None:
            raise RedisError("redis连接池未初始化")
        return cls.__redis_pool
